package com.pentofab.payrollmanagement.ui.controller;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ResourceBundle;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;

import com.pentofab.payrollmanagement.application.PayrollApplicationFactory;
import com.pentofab.payrollmanagement.dao.AttendanceDao;
import com.pentofab.payrollmanagement.dao.EmployeeDao;
import com.pentofab.payrollmanagement.dao.model.Company;
import com.pentofab.payrollmanagement.dao.model.Department;
import com.pentofab.payrollmanagement.dao.model.Designation;
import com.pentofab.payrollmanagement.dao.model.EmpCategory;
import com.pentofab.payrollmanagement.dao.model.Employee;
import com.pentofab.payrollmanagement.dao.model.UserAccounts;
import com.pentofab.payrollmanagement.ui.control.CustomTime;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;

public class CompanyAttendanceTabController  extends AbstractUIController implements FormValidator {

	@FXML
	Parent root;
	@FXML
	private ListView<String> attendanceModuleList;
	@FXML
	private TextField empId; 
	@FXML
	private ChoiceBox<String> from_date; 
	@FXML
	private ChoiceBox<String> from_month; 
	@FXML
	private ChoiceBox<String> from_year; 
	@FXML
	private CustomTime totalLogTime; 
	
	@FXML
	TextField importFileLoc;
	@FXML
	TextField exportFileLoc;
	@FXML
	
	private Company company;
	private UserAccounts userAccounts;
	
	EmployeeDao employeeDao = PayrollApplicationFactory.getEmployeeMgmt();
	AttendanceDao attendanceDao = PayrollApplicationFactory.getAttandanceMgmt();
	
	@Override
	public Parent getView() {
		return root;
	}

	@Override
	public String getTitle() {

		return "Attendance View";
	}
	public void save(){
		
		String fromDate = from_date.getSelectionModel()
				.getSelectedItem()
				+ "-"
				+ (from_month.getSelectionModel()
						.getSelectedIndex() + 1)
				+ "-"
				+ from_year.getSelectionModel()
						.getSelectedItem();
		
		String emmployeeId = empId.getText().trim();
		String in = "00:00";
		String out = totalLogTime.getText();
		out = out.replace(".", ":");
		if(!PayRollUtility.validateTime(out)){
			
			showError("Please enter valid total hours.");
		}
		
		try{
		
			Date date = PayRollUtility.convertStringToDate(fromDate);
			PayRollUtility.compareInOutTime(in, out);
			employeeDao.getEmpById(emmployeeId);
			attendanceDao.addAttandeanceEntry(emmployeeId, date, in, out, userAccounts.getUsername(), 1, true, true);
			
		}catch(Exception e){
			
			showError(e.getMessage());
			
		}
		
		empId.clear();
		totalLogTime.clear();
	}
	public void reset(){
		
		refreshUI();
	}

	@Override
	public void refreshUI(Object... args) {
		
		
		if (args != null && args.length > 0) {
			Company company = (Company) args[0];
			this.company = company;
			
			if(args.length > 1 && args[1] instanceof UserAccounts){
				userAccounts = (UserAccounts) args[1];
			}
		}
		importFileLoc.clear();
		exportFileLoc.clear();
		empId.clear();
		totalLogTime.clear();
		from_date.getSelectionModel().clearSelection();
		from_year.getSelectionModel().clearSelection();
		from_date.getSelectionModel().clearSelection();

	}
	
	
	public void open() {
		System.out.println("Open");
		if(attendanceModuleList.getSelectionModel().getSelectedIndex() == 0)
			PayrollApplicationFactory.getMainController().showScreen("AddAttentanceEntry.fxml", true, this.company,userAccounts);
		if(attendanceModuleList.getSelectionModel().getSelectedIndex() == 1)
			PayrollApplicationFactory.getMainController().showScreen("Dislpay_Attendance.fxml", true, this.company,userAccounts);
	}

	public void goBack() {

		PayrollApplicationFactory.getMainController().showScreen(
				MainController.COMPANIES_LIST_SCREEN, false, userAccounts);
	}

	@Override
	public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
		
		ArrayList<String > yearList = new ArrayList<String>();
		int year = PayRollUtility.getYear() - 1;
		for (int i = 0; i < 5; i++) {
			yearList.add(year + "");
			year++;
		}
		
		from_year.getSelectionModel().selectedIndexProperty()
		.addListener(new ChangeListener<Number>() {

			@Override
			public void changed(ObservableValue arg0, Number arg1,
					Number arg2) {
				from_month.getSelectionModel().clearSelection();
			}

		});
		
		from_month.getSelectionModel().selectedIndexProperty()
		.addListener(new ChangeListener<Number>() {

			@Override
			public void changed(ObservableValue arg0, Number arg1,
					Number arg2) {

				from_date.getSelectionModel().clearSelection();
				from_date.getItems().clear();
				ArrayList<String> fromMonthDaysList = new ArrayList<String>();
				
				if(from_month.getSelectionModel().getSelectedIndex()< 0)
					return;
				System.out.println(from_date.getItems());
				int fromMaxDay = PayRollUtility.getMaxDayofMonth(Integer
						.parseInt(from_year.getSelectionModel()
								.getSelectedItem()), from_month
						.getSelectionModel().getSelectedIndex());
				for (int i = 1; i <= fromMaxDay; i++) {

					fromMonthDaysList.add(i + "");
				}
				from_date.getItems().addAll(fromMonthDaysList);

			}

		});
		from_year.getItems().addAll(yearList);
		attendanceModuleList.getItems().add("Add Attedance Entry");
		attendanceModuleList.getItems().add("View Attandance Detail");
	}

	@Override
	public boolean isValid() {
		return false;
	}

	@Override
	public String getValidationMessage() {
		
		if (from_year.getSelectionModel().getSelectedIndex() < 0) {
			return "Select valid year";
		}
		if (from_month.getSelectionModel().getSelectedIndex() < 0) {
			return "Select valid month";
		}
		if (from_date.getSelectionModel().getSelectedIndex() < 0) {
			return "Select valid date";
		}
		return "";
	}
	
	
	public void browseImport(){

		try{
			FileChooser fileChooser = new FileChooser(); 
			fileChooser.setTitle("Select Attendfance File");

			File file = fileChooser.showOpenDialog(null);
			File destinationFile = new File(file.getAbsolutePath());
			String fileName = destinationFile.getName();
			if(file!=null && !file.isDirectory()){

				importFileLoc.setText(destinationFile.getAbsolutePath());
				if(fileName !=null && !fileName.equals(UIMessages.FileName.ATT_LIST)){
					showError("To import Attendance, Please select file having name  :"+UIMessages.FileName.ATT_LIST);
					refreshUI();
					return;
				}


				FileReader fr = new FileReader(file);

				BufferedReader br = new BufferedReader(fr);
				String colnms = br.readLine();
				System.out.println("Column names : "+colnms);
				if(colnms == null || colnms.trim().equals("")){
					showError("No data in file : "+fileName);
					refreshUI();
					br.close();
					return;
				}else if(!colnms.equalsIgnoreCase("EMPID,EmpName,Date,IN(HH:MM),OUT(HH:MM),TOTAL")){
				
					showError("Invalid column, column name should be in EMPID,EmpName,Date,IN(HH:MM),OUT(HH:MM),TOTAL order");
					refreshUI();
					br.close();
					return;
				}


				String[] colArray = colnms.split(",");
				if(colArray == null || colArray.length != 6	){

					showError("Improper data in file : "+fileName+", Valid data must contain only \n"
							+ "EMPID,EmpName,Date,IN(HH:MM),OUT(HH:MM),TOTAL");
					br.close();
					refreshUI();
					return;
				}
				br.close();

			}else{
				showInfo("Import Operation cancelled as file not selected for import.");
				refreshUI();
				return;
			}

		}catch(Exception e){
			refreshUI();
			showError("Error while importing Attendance data.");
		}
	}

	public void importSubmit(){

		try{
			


			File file = new File(importFileLoc.getText().trim());
			ArrayList<HashMap<String, String>> attendanceInfo = new ArrayList<HashMap<String,String>>();
			FileReader fr = new FileReader(file);
			BufferedReader br = new BufferedReader(fr);
			String[] clnmsArray = br.readLine().split(",");
			String dataLine = null;
			while((dataLine = br.readLine()) != null){
				System.out.println("dataLine : "+dataLine);
				String[] data = dataLine.split(",");

				HashMap<String, String> cur = new HashMap<String, String>();
				for(int i= 0;i < data.length;i++){

					cur.put(clnmsArray[i],data[i].replaceAll("'", ""));
				}
				System.out.println("cur : "+cur);
				attendanceInfo.add(cur);

			}

			System.out.println("attendanceInfo size : "+attendanceInfo.size());
			Iterator<HashMap<String, String>> attendanceInfoMapIterator = attendanceInfo.iterator();
			StringBuffer errorBuffer = new StringBuffer();
			while(attendanceInfoMapIterator.hasNext()){
				try{

				HashMap<String, String > current = attendanceInfoMapIterator.next();
				
				Date date = PayRollUtility.convertStringToDate(current.get("Date"));
					attendanceDao.addAttandeanceEntry(current.get("EMPID"), date, current.get("IN(HH:MM)"), current.get("OUT(HH:MM)"), 
							userAccounts.getUsername(), -1, true, true);
				}catch(Exception e){
					e.printStackTrace();
					errorBuffer.append(e.getMessage());
				}
			}

			if(!errorBuffer.toString().equals("")){
				
				System.out.println("errorBuffer : "+errorBuffer);
				showError("Failed to add following Attendance entry due to data error,\n1. Invalid or Non-existing empid\n"
						+ "2. Invalid in or out time.\n"+errorBuffer);
			}

			refreshUI();
			br.close();
		
		}catch(Exception e){
			e.printStackTrace();
			refreshUI();
			showError("Error while importing company data.");
		}

	}

	public void browseExport(){


		if(from_year.getSelectionModel().getSelectedIndex()  < 0 || 
				from_month.getSelectionModel().getSelectedIndex()  < 0){
			showError("Please select year and monthto export.");
			refreshUI(null);
			return;
		}
		try{
			DirectoryChooser fileChooser = new DirectoryChooser(); 
			fileChooser.setTitle("Select Destination");
			
			File file = fileChooser.showDialog(null);
			File destinationFile = new File(file.getAbsolutePath());
			if(file!=null && file.isDirectory()){

				exportFileLoc.setText(destinationFile.getAbsolutePath());

			}else{
				showInfo("Export Operation cancelled as Directory nor selected for export.");
				refreshUI();
				return;
			}

		}catch(Exception e){
			refreshUI();
			showError("Error while exporting Employee data.");
		}

	}
	public void exportSubmit(){
		try{
			
			
			String fromDate = "01-"+(from_month.getSelectionModel().getSelectedIndex()+1)+"-"+from_year.getSelectionModel().getSelectedItem();
			
			String toDate = from_date.getItems().get(from_date.getItems().size()-1)+"-"+
					(from_month.getSelectionModel().getSelectedIndex()+1)+"-"+from_year.getSelectionModel().getSelectedItem();
			String empId1 = (empId.getText() != null && !empId.getText().trim().equals("")) ? empId.getText() : null;
			System.out.println("empId1 : "+empId1);
			System.out.println("fromDate : "+fromDate);
			System.out.println("toDate : "+toDate);
			System.out.println("empId1 : "+empId1);
			ArrayList<HashMap<String,String>> attinfo = attendanceDao.employeeTimesheetInfo(empId1, company.getCompanyID(), null, fromDate, toDate, null, 1);
			System.out.println("attinfo : "+attinfo);
			
			

			File file = new File(exportFileLoc.getText()+"//"+UIMessages.FileName.ATT_LIST);
			FileWriter fw =new FileWriter(file,true);
			BufferedWriter bw =new BufferedWriter(fw);
			bw.write("EMPID,EmpName,Date,IN(HH:MM),OUT(HH:MM),TOTAL\n");

			for(int i=0; i < attinfo.size();i++){


				HashMap<String,String> attInfoMap =attinfo.get(i);

				StringBuffer dataLine = new StringBuffer();
				dataLine.append(attInfoMap.get("eid")).append(",");
				dataLine.append(attInfoMap.get("name")).append(",");
				dataLine.append(attInfoMap.get("attDate")).append(",");
				dataLine.append(attInfoMap.get("from_time")).append(",");
				dataLine.append(attInfoMap.get("to_time")).append(",");
				dataLine.append(attInfoMap.get("total"));

				bw.write(dataLine.toString()+"\n");
			}

			showInfo("Successfuly exported Attendance info.");
			bw.flush();
			fw.flush();
			bw.close();fw.close();
			refreshUI(null);
			
		}catch(Exception e){
			e.printStackTrace();
			showError("Error while exporting company data.");
		}

	}
}
